<?php

namespace App\Repository\Repositories;


use App\Helpers\Token;
use App\Http\Controllers\Controller;
use App\Http\Serve\Express;
use App\Http\Service\OrderNumberGeneration;
use App\Http\Service\Redisd;
use App\Models\StoreCategory;
use App\Models\StoreCouponIssueUser;
use App\Models\StoreOrder;
use App\Models\StoreProduct;
use App\Models\StoreProductReply;
use App\Models\StoreProductRule;
use App\Models\StoreVisit;
use App\Repository\RepositoryInterface\ProductInterface;
use Carbon\Carbon;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;



class ProductRepositories extends Controller implements ProductInterface
{
    protected $key='visitRankList';
    /**
     * @param $arr
     * @return int|mixed
     * 添加商品的规格
     */
    public function AddMoreSpec($arr)
    {
        // TODO: Implement AddMoreSpec() method.
        $arr=$arr['ruleList'];
        foreach ( $arr as $key=>$value)
        {
            $value=json_decode($value,true);
            $param['rule_name']=$value['name'];
            $param['rule_value']=json_encode($value['valueList']);
            try {
                $StoreProduce=new StoreProductRule();
                $res=$StoreProduce->AddRules($param);

            } catch (\Exception $exception)
            {
                return  $exception->getMessage();
            }
        }
    }
    /**
     * @param $id
     * @return array|void
     * 规格删除
     */
    public function AttrDel($id)
    {
        $rule=new StoreProductRule();
        $res=$rule->RuleDel($id);
        if($res)
        {
            return success('删除成功','');
        }
        else
        {
            return  fail('删除失败');
        }
    }
    /**
     * 商品列表
     * @return mixed
     */
    public function goodsList($where)
    {
        return StoreProduct::where('is_del',0)->where('is_show',1)->where($where)->get();
    }


    /**
     * 商品排行榜
     * @param $id
     * @param $ids
     * @return mixed
     */
    public function goodsRank($id, $ids)
    {
        return StoreProduct::whereIn('id', $id)
            ->orderByRaw(DB::raw("FIELD(id, $ids)"))->get();
    }

   
    /**
     * 获取分类列表
     * @return mixed
     */
    public function index($where)
    {
        return StoreCategory::where($where)->get();

    }

    public function categoryList()
    {
        return StoreCategory::get();
    }
    /**
     * 数据添加入库
     * @param $data
     * @return mixed
     */
    public function save($data)
    {
        return StoreCategory::create($data);
    }
    /**
     * 修改之前的查询
     * @param $id
     * @return mixed
     */
    public function edit($id)
    {
        return StoreCategory::where('id', $id)->first();
    }
    /**
     * 分类修改
     * @param $id
     * @param $data
     * @return mixed
     */
    public function update($id, $data)
    {
        return StoreCategory::where('id', $id)->update($data);
    }

    /**
     * 商品分类详情
     * @param $id
     * @return mixed
     */
    public function read($id)
    {
        return StoreCategory::where('id', $id)->first();
    }

    /**
     * 商品分类删除
     * @param $id
     * @return mixed
     */
    public function delete($id)
    {
        return StoreCategory::where('id', $id)->delete();
    }
    /**
     * 状态修改
     * @param $id
     * @return mixed
     */
    public function change($id)
    {
        $data = StoreCategory::where('id', $id)->first();
        if ($data->is_show == 1) {
            $data->is_show = 0;
        } else {
            $data->is_show = 1;
        }
        return $data->save();
   }


    /**
     * @return mixed
     * 规格列表
     */
    public function AttrRuleList()
    {
        // TODO: Implement test() method.
        $arr=StoreProductRule::get();
        return $arr;
    }
    /**
     * wf
     * 商品预售接口
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function activeGoods(){
        try {
            $activeGoods = StoreProduct::activeGoods();
            foreach ($activeGoods as &$v){
                for ($i=0;$i<$v['active_num'];$i++) {
                    Redisd::getInstance()->lPush("active_goods".$v['id'],$v['id']);
                }
                $v['slider_image'] = explode(',',$v['slider_image']);
                $newDate = date('Y-m-d H:i:s');
                $timeDiff = Carbon::parse($v['active_time'])->diffInSeconds($newDate);
                $v['active_time'] = $timeDiff;
            }
            return parent::success("查询成功",$activeGoods);
        }catch (\Exception $exception){
            return parent::error($exception->getMessage());
        }
    }

    /**
     * wf
     * 预售详情
     * @param $id
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function activeItem($id){
        try {
            $activeItem = StoreProduct::activeItem($id);
            $activeItem['slider_image'] = explode(',',$activeItem['slider_image']);
            return parent::success("查询成功",$activeItem);
        } catch (\Exception $exception) {
            return parent::error($exception->getMessage());
        }
    }

    /**
     * wf
     * 预售商品抢购
     * @param $id
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function deposit($params){
        DB::beginTransaction();
        try {
            $activeItem = StoreProduct::activeItem($params['id']);
            if ($activeItem['active_time']<strtotime(date('Y-m-d H:i:s'))){
                if (Redisd::getInstance()->lLen("active_goods".$params['id'])>0){
                    Redisd::getInstance()->lPop("active_goods".$params['id']);
                    $uid = Token::verifyToken($params['token']);
                    $data = [
                        'uid'=>$uid,
                        'real_name'=>$params['real_name'],
                        'user_phone'=>$params['user_phone'],
                        'user_address'=>$params['user_address'],
                        'total_num'=>$params['total_num'],
                        'total_price'=>$params['total_price'],
                        'pay_postage'=>$params['pay_postage'],
                        'deduction_price'=>$params['deduction_price'],
                        'coupon_id'=>$params['coupon_id'],
                        'coupon_price'=>$params['coupon_price'],
                        'active_status'=>0,
                        'goods_id'=>$params['id'],
                        'bargain'=>$params['bargain'],
                        'add_time'=>time()
                    ];
                    $data['order_id'] = OrderNumberGeneration::createOnlyId();
                    $orderStatus = StoreOrder::OrderCreate($data);
                    $goods = $activeItem;
                    $minCount = StoreProduct::where('id',$params['id'])->increment('active_num',-1);
                    if (!$minCount){
                        return parent::error("下单失败");
                    }
                    if (!empty($params['coupon_id'])){
                        StoreCouponIssueUser::where('uid',$uid)->where('issue_coupon_id',$params['coupon_id'])->update(['status'=>1]);
                    }
                    DB::commit();
                    return parent::success("抢购成功");
                }else{
                    return parent::error("该商品预售已售空");
                }
            }else {
                return parent::error("商品预售时间已过");
            }
        }catch (\Exception $exception){
            DB::rollBack();
            return parent::error($exception->getMessage());
        }
    }

    /**
     * @param $rate1
     * @param $rate2 @登录用户访问的数据
     * @return float|int
     * 计算曼哈顿距离算法 cqf
     */
    public function manhattan($rate1, $rate2)
    {
        //$rate1 代表循环出入的用户 $rate2指的是recommend方法第一个参数  可以理解为登录的用户id
        $distance = 0;
        if (is_array($rate1) && count($rate1) > 0) {
            foreach ($rate1 as $name => $value1) {
                //判断当前登录的用户是否存在对应的键   个人理解: 例如其他用户访问了苹果  登录用户也访问了苹果仿品 则获取当前登录用户对苹果商品访问的次数值
                if (isset($rate2[$name]) == true) {
                    $value2 = $rate2[$name];
                    $distance += abs($value1 - $value2);
                } else {
                    $distance += 0;
                }
            }
        } else {
            $distance = -1;
        }
        return $distance;
    }

    /**
     * @param $user_id
     * @param $id
     * @param $test @用户 访问了那件商品及对应的访问次数  处理好的二维数组
     * @param $nearest @最近的用户id
     * @return mixed|void
     * 精品促销推荐 cqf
     */
    public function recommend($user_id, $id)
    {

        $uid = [];
        $visit = StoreVisit::get()->toArray();
        foreach ($visit as $v) {
            $uid[] = $v['uid'];
        }
        //1 去重  获取浏览表当中更多每个uid 以及每个用户对应 访问的商品跟浏览次数
        $uid = array_unique($uid);
        $test = [];
        foreach ($uid as $v) {
            $test[$v] = [];
            foreach ($visit as $vv) {
                if ($vv['uid'] == $v) {
                    //uid当做键名  值为 商品id跟访问次数  uid=>['product_id'=>count]
                    $test[$v][$vv['product_id']] = $vv['count'];
                }
            }
        }
        //2 计算最趣味相投的用户
        $distances = array();
        if (is_array($test) && count($test) > 0) {
            foreach ($test as $key => $value) {
                //理解:  因为这边只需要计算当前登录用户与其他用户的距离 需要排除自己
                if ($key == $user_id) {
                    continue;
                }
                $distance = $this->manhattan($value, $test[$user_id]);
                $data = array(
                    'user' => $key,
                    'distances' => $distance
                );
                $distances[] = $data;
            }
        }
        array_multisort(array_column($distances, 'distances'), SORT_ASC, $distances);
        //distances为0 两种情况 一种是当前登录用户与对比的用户所看的所有商品浏览次数一模一样  第二种:对比的用户看的  登录用户没看就不会有距离值
        foreach ($distances as $key => $value) {
            if ($value['distances'] == 0) {
                unset($distances[$key]);
            }
        }
        foreach ($distances as $key => $val) {
            $nearest = $val['user'];
            break;
        }
        $recommendations = array();
        //获取最近用户的浏览列表
        $neighborRatings = $test[$nearest];
        if (is_array($neighborRatings) && count($neighborRatings) > 0) {
            $usernameAction = $test[$user_id];
            foreach ($neighborRatings as $name => $code) {
                //读取自己没有的
                if (!isset($usernameAction[$name])) {
                    $recommendations[] = ['name' => $name, 'score' => $code];
                }
            }
        }

        array_multisort(array_column($recommendations, 'score'), SORT_DESC, $recommendations);
        $recommendproduct = array();
        foreach ($recommendations as $key => $val) {
            $data = StoreProduct::where('id', $val['name'])->first()->toarray();
            array_push($recommendproduct, $data);
        }
        return json_encode([
            'code' => 200,
            'data' => $recommendproduct,
            'msg' => '促销精品推荐获取成功'
        ]);
    }

    /**
     * @return mixed|void
     * 促销精品方法
     */
    public function productList()
    {

        try {
            $product_data = StoreProduct::where('is_best', 1)
                ->where('is_del', 0)
                ->where('active_time','>=',date('Y-m-d h-m-s'))
                ->paginate(3)
                ->toarray();
            foreach ($product_data['data'] as $key=>&$val){
                $val['active_time']=$val['active_time']-time();
            }
            return parent::success('列表获取成功', $product_data);
        }catch (QueryException $queryException){
            return parent::error('获取失败',$queryException->getMessage());
        }
    }

    /**
     * @param $storeproduct_id
     * @return mixed|void
     * 促销精品详情
     */
    public function productdetail($storeproduct_id)
    {
        try {
            $data = StoreProduct::where('id', $storeproduct_id)->first()->toarray();

            $data['slider_image'] = explode(',', $data['slider_image']);
            return parent::success('获取详情成功', $data);
        }catch (QueryException $queryException){
            return parent::error('获取失败',$queryException->getMessage());
        }

    }

    /**
     * @param $storeproduct_id
     * @param $type
     * @return \Illuminate\Http\JsonResponse|mixed
     * 商品详情评论查询
     */
    public function productRemarklist($storeproduct_id, $type)
    {
        if ($type == "limit") {
            try {
                $data = StoreProductReply::where('product_id', $storeproduct_id)->limit(3)->get()->toarray();
                return parent::success('获取成功', $data);
            } catch (QueryException $queryException) {
                return parent::error('获取失败', $queryException->getMessage());
            }
        } else {
            try {
                $data = StoreProductReply::where('product_id', $storeproduct_id)->get()->toarray();
                return parent::success('获取成功', $data);
            } catch (QueryException $queryException) {
                return parent::error('获取失败', $queryException->getMessage());
            }
        }
    }

    /**
     * @return \Illuminate\Http\JsonResponse|mixed
     * 商品浏览量排行榜 cqf
     */
    public function productRankList()
    {
        try {
            $data=DB::select('SELECT product_id,SUM(count) as count FROM tg_store_visit GROUP BY product_id');
            foreach ($data as $val){
                Redisd::getInstance()->zAdd($this->key,[$val->count=>$val->product_id]);
            }
            //根据浏览量个数 从大到小排序
            $res=Redisd::getInstance()->zRevRange($this->key,0,10);
            $rankData=[];
            foreach ($res as $v){
                $product_data=StoreProduct::where('id',$v)->first()->toarray();
                //个数
                $count=Redisd::getInstance()->zScore($this->key,$v);
                array_push($rankData,['store_name'=>$product_data['store_name'],'count'=>$count]);
            }
            return  parent::success('获取成功',$rankData);
        }catch (QueryException $queryException){
            return parent::error($queryException->getMessage(),[]);
        }
    }
}
